package istar.behaviour;

import istar.IBasicElement;
import istar.IElement;
import istar.IElementLink;
import istar.agent.IstarJadeAgent;
import istar.impl.Task;
import jade.core.behaviours.Behaviour;
import jade.core.behaviours.ParallelBehaviour;

import java.util.Iterator;
import java.util.Vector;

import log.Log;

public class IstarParallelBehaviour extends ParallelBehaviour{

	private IElement endElement;
	private boolean log = true;
	private Behaviour subBehaviour = null;

	
	public IstarParallelBehaviour(IstarJadeAgent _agent, IElement endElement, int endCondition){
		super(_agent, endCondition);
		this.endElement = endElement;
		this.setBehaviourName(endElement.getName());
		//performBehaviour();
	}
	
	public IstarParallelBehaviour(IElement endElement, int endCondition){
		super(endCondition);
		this.endElement = endElement;
		this.setBehaviourName(endElement.getName());
		//performBehaviour();		
	}
	
	
	@Override
	public void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
		performBehaviour();
	}

	private void performBehaviour(){
		//System.out.println(" - Behaviour " + this.getClass().getName() + ":" + this.getBehaviourName()+ " created");
		Vector<IElement> subElements = new Vector<IElement>();

		Iterator<IElement> itSubElements = null; 
		
		if (this.endElement.getClass()==Task.class){
			itSubElements = ((Task)endElement).getMyDecompositionLink().getTargetElements().iterator();
		}
		else {
			itSubElements = endElement.getMeansEndLink().getTargetElements().iterator();
		}
		
		while (itSubElements.hasNext()){
			subElements.add(itSubElements.next());
		}
		
		Iterator<IElement> itElmnts = subElements.iterator();
		while (itElmnts.hasNext()){
			IElement subElemnt = itElmnts.next();
			// if subElemnt is internal
			if (subElemnt.getOwner()==endElement.getOwner()){
				if (subElemnt.isBasic()){
					//this.addSubBehaviour(((IBasicElement)subElemnt).getBehaviour());
					subBehaviour = ((IBasicElement)subElemnt).getBehaviour();
				}
				else{
					if (subElemnt.getClass()==Task.class){
						 if (((Task)subElemnt).getMyDecompositionLink().getType()==IElementLink.SEQUENTIAL){
							//this.addSubBehaviour(new SequentialTaskBehaviour((IstarJadeAgent)this.myAgent, (Task)subElemnt));
							subBehaviour = new SequentialTaskBehaviour((IstarJadeAgent)this.myAgent, (Task)subElemnt);
						}
						else if (((Task)subElemnt).getMyDecompositionLink().getType()==IElementLink.PARALLEL){
							//this.addSubBehaviour(new IstarParallelBehaviour((IstarJadeAgent)this.myAgent, (Task)subElemnt, ParallelBehaviour.WHEN_ALL));
							subBehaviour = new IstarParallelBehaviour((IstarJadeAgent)this.myAgent, (Task)subElemnt, ParallelBehaviour.WHEN_ALL);
						}
					}
					else {
						if (subElemnt.getMeansEndLink().getType()==IElementLink.PARALLEL){
							//this.addSubBehaviour(new IstarParallelBehaviour((IstarJadeAgent)this.myAgent, subElemnt, ParallelBehaviour.WHEN_ANY));
							subBehaviour = new IstarParallelBehaviour((IstarJadeAgent)this.myAgent, subElemnt, ParallelBehaviour.WHEN_ANY);
						}
						else if (subElemnt.getMeansEndLink().getType()==IElementLink.UNIQUE){
							//this.addSubBehaviour(new MeansEndUniqueBehaviour((IstarJadeAgent)this.myAgent, subElemnt));
							subBehaviour = new MeansEndUniqueBehaviour((IstarJadeAgent)this.myAgent, subElemnt);
						}
					}
				}
				
			}
			// subElemnt is external
			else {
				subBehaviour = new RequestExternalElement((IstarJadeAgent)this.myAgent, subElemnt);
			}
			log("<behaviour type=" + getClass().getName() + " name="+ getBehaviourName() + " adding subBehaviour >"); 
			log("	<behaviour type=" + subBehaviour.getClass().getName() + " name="+ subBehaviour.getBehaviourName() + " />");
			log("</behaviou>");
			this.addSubBehaviour(subBehaviour);

		}
		
	}

	@Override
	public int onEnd() {
		log("<behaviour type=" + getClass().getName() + " name="+ getBehaviourName() + " ending />");
		/*
		if (endElement.achieved()){
			return 1;
		}
		else {
			return 0;
		}
		*/
		return subBehaviour.onEnd();
		
			

	}
	
	public void log(String _phrase){
		if (this.log){
			((IstarJadeAgent)myAgent).log( _phrase);
		}
	}

	
}
